/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package heartsserver;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author quangduc
 */
public class Al implements Runnable {

    private int first = 1;
    private Socket socket = null;
    private Thread thread = null;
    private DataInputStream console = null;
    private DataOutputStream streamOut = null;
    private ThreadAl threadAl = null;
    private Random random = new Random();
    public int num = -1;
    public int type = -1;
    ArrayList<Card> dsCardPlayer = new ArrayList<>();
    ArrayList<Card> dsBaiTrenBan = new ArrayList<>();
    public int soTran = 1;
    int Cardcount = 0;
    public int playerID = -1;
    Card baiDanhRa;

    public Al(String sIP, int serverPort) {
        System.out.println("Establishing connection. Please wait ...");
        try {
            socket = new Socket(sIP, serverPort);
            System.out.println("Connected: " + socket);
            start();
        } catch (UnknownHostException uhe) {
            System.out.println("Host unknown: " + uhe.getMessage());
        } catch (IOException ioe) {
            System.out.println("Unexpected exception: " + ioe.getMessage());
        }
    }

    @Override
    public void run() {
        while (thread != null) {
            try {
                streamOut.writeUTF(console.readLine());
                streamOut.flush();
            } catch (IOException ioe) {
                System.out.println("Sending error: " + ioe.getMessage());
                stop();
            }
        }
    }

    public void send(String msg) {

        try {
            streamOut.writeUTF(msg);
            streamOut.flush();
        } catch (IOException ioe) {
            System.out.println("Sending error: " + ioe.getMessage());
            stop();
        }

    }
    //Ham xu ly doi bai: Cap nhat lai trang thai cua quan bai (doi info cua nguoi choi)

    public void XuLyNhanBai(String msg) {
        System.out.println("\nAl nhan message " + msg);
        String[] parameterArray = msg.split(" ");
        int code = Integer.parseInt(parameterArray[0]);
        String sentMsg;
        switch (code) {
            case 5:
                send("1 "+playerID);
                break;
            case 6: //Nhan bai duoc chia         
                //        System.out.println("So luong: " + parameterArray.length);
                int i;
                if (parameterArray.length < 28) {
                    //Thông báo tới lượt đi
                    chonBaiDanh();
                    System.out.println("\nNguoi choi bat dau: "
                            + parameterArray[0] + " " + parameterArray[1]);
                } else {
                    //Nhan bai chia
                    dsCardPlayer.clear();
                    playerID = Integer.parseInt(parameterArray[1]);
                    i = 2;
                    for (; i < parameterArray.length; i = i + 2) {
                        //System.out.println(baiDuocChia[i] + " ");
                        num = Integer.valueOf(parameterArray[i]);
                        type = Integer.valueOf(parameterArray[i + 1]);
                        Card card = new Card(num, type, playerID);
                        dsCardPlayer.add(card);
                    }
                    chonBaiDoi();
                    System.out.printf("\nBai duoc chia player %d :%d length \n", playerID, Cardcount);
                    for (Card c : dsCardPlayer) {
                        System.out.print(c.getNumber() + " " + c.getType());
                    }
                }
                break;
            case 7://Gưi thông tin bài đánh ra của player khác
                int id = Integer.parseInt(parameterArray[1]);
                num = Integer.parseInt(parameterArray[2]);
                type = Integer.parseInt(parameterArray[3]);
                Card card = new Card(num, type, id);
                baiNguoiChoi(card);
                break;
            case 12: //Doi bai
                int playerID = Integer.parseInt(parameterArray[1]);
                for (i = 2; i < parameterArray.length; i = i + 2) {
                    //System.out.println(baiDuocChia[i] + " ");     
                    num = Integer.valueOf(parameterArray[i]);
                    type = Integer.valueOf(parameterArray[i + 1]);
                    //Add 3 quan bài mới đổi
                    Card c = new Card(num, type, playerID);
                    dsCardPlayer.add(c);
                }
                sapCardTang();
                xacDinh2Chuon();
                break;
        }

    }

    public void start() throws IOException {
        console = new DataInputStream(System.in);
        streamOut = new DataOutputStream(socket.getOutputStream());
        if (thread == null) {
            threadAl = new ThreadAl(this, socket);
            thread = new Thread(this);
            thread.start();
        }
    }

    public void stop() {
        if (thread != null) {
            thread.stop();
            thread = null;
        }
        try {
            if (console != null) {
                console.close();
            }
            if (streamOut != null) {
                streamOut.close();
            }
            if (socket != null) {
                socket.close();
            }
        } catch (IOException ioe) {
            System.out.println("Error closing ...");
        }
        threadAl.close();
        threadAl.stop();
    }

    public void chonBaiDoi() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Al.class.getName()).log(Level.SEVERE, null, ex);
        }
        int[] dsChon = new int[3];
        int index = 0;
        for (int i = 0; i < 3; i++) {
            int vitri = random.nextInt(13);
            //ktra vitri tao ra co truoc do chua
            int flag = 1;
            for (int j = 0; j < index; j++) {
                if (dsChon[j] == vitri) {
                    flag = 0;
                }
            }
            if (flag == 1) {
                dsChon[index++] = vitri;
            } else {
                i--;
            }
        }
        ArrayList<Card> temp = new ArrayList<>();
        for (int i = 0; i<index; i++){
            temp.add(dsCardPlayer.get(i));
        }        
        String msg = "12 " + playerID;
        for (Card card:temp) {
            msg += " " + card.getNumber();
            msg += " " + card.getType();
            dsCardPlayer.remove(card);
        }
        send(msg);
        System.out.println("\nAL "+playerID+" Send 3 Card: " + msg);
    }

    public void baiNguoiChoi(Card card) {
        dsBaiTrenBan.add(card);
        ktraKetQua();
    }

    //Ham kiểm tra lá bài có thỏa điều kiện đánh hay không
    public int KiemTraLaBai(Card BaiDanh, Card BaiDauTien) {
        int flag = 1; //Quan bai thoa dieu kien
        if (BaiDanh.getType() != BaiDauTien.getType()) {
            flag = 0;
        }
        return flag;

    }

    public void xacDinh2Chuon() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Al.class.getName()).log(Level.SEVERE, null, ex);
        }
        int vt = -1;
        for (Card card : dsCardPlayer) {
            if (card.getNumber() == 0 && card.getType() == 1) {
                card.setIsUse(true);
                baiDanhRa = card;
                dsBaiTrenBan.add(card);
                String msg = "7 " + playerID;
                msg += " " + card.getNumber() + " " + card.getType();
                System.out.println("\nAl " + playerID +" send card: " + msg);
                send(msg);
                break;
            }
        }
    }

    public void ktraKetQua() {
        if (dsBaiTrenBan.size() >= 4) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Al.class.getName()).log(Level.SEVERE, null, ex);
            }
            Card cardDau = dsBaiTrenBan.get(0);
            if (cardDau.getType() == baiDanhRa.getType()) {
                int flag = 1;//Lớn nhất
                for (Card card : dsBaiTrenBan) {
                    //Nếu cùng chất và nhỏ hơn 1 con nào đó
                    if (card.getType() == baiDanhRa.getType() && baiDanhRa.getNumber() < card.getNumber()) {
                        flag = 0;//Không lớn nhất
                        break;
                    }
                }
                //Tính điểm
                if (flag == 1) {//Lớn nhất
                    int diemSo = 0;
                    for (Card card : dsBaiTrenBan) {
                        if (card.getType() == 3) {//Bài chất cơ
                            diemSo++;
                        } else if (card.getNumber() == 10 && card.getType() == 0) {//Con Q bích
                            diemSo += 13;
                        }
                    }
                    //Send điểm
                    String msg = "2 " + playerID + " " + diemSo;
                    send(msg);
                }
            }
            dsBaiTrenBan.clear();
        }
    }

    public void sapCardTang() {
        for (int i = 0; i < dsCardPlayer.size() - 1; i++) {
            for (int j = i + 1; j < dsCardPlayer.size(); j++) {
                if (dsCardPlayer.get(j).isLower(dsCardPlayer.get(i))) {
                    Card temp = dsCardPlayer.get(i);
                    dsCardPlayer.set(i, dsCardPlayer.get(j));
                    dsCardPlayer.set(j, temp);
                }
            }
        }
    }

    public boolean ktraLuat(Card card) {
        //Đi con thứ nhất trong 4 con bài trên bàn
        if (dsBaiTrenBan.size() <= 0) {
            if (card.getNumber() == 0 && card.getType() == 1) {
                return true;
            }
            for (Card c : dsCardPlayer) {
                if (c.isIsUse() == false && c.getNumber() == 0 && c.getType() == 1)//2 chuồn
                {
                    return false;
                }
            }
        } else {
            Card cardDau = dsBaiTrenBan.get(0);
            //Nếu cùng chất (dạng) với lá bài đầu
            if (cardDau.getType() == card.getType()) {
                return true;
            }
            //Duyệt dsCardPlayer tìm con cùng chất
            for (Card c : dsCardPlayer) {
                if (c.isIsUse() == false && cardDau.getType() == c.getType()) {//Có con cùng chất phải đánh con cùng chất
                    return false;
                }
            }
        }
        //Không tìm thấy con nào cũng chất        
        return true;
    }

    public void chonBaiDanh() {
        for (Card card : dsCardPlayer) {
            if (card.isIsUse() == false) {//Chưa đánh ra
                if (ktraLuat(card) == true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Al.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    baiDanhRa = card;
                    card.setIsUse(true);
                    dsBaiTrenBan.add(card);
                    String msg = "7 " + playerID;
                    msg += " " + card.getNumber() + " " + card.getType();
                    System.out.println("Al send card: " + msg);
                    send(msg);
                    ktraKetQua();
                    break;
                }

            }
        }
        System.out.println("Chon Bai Danh Ra Xong");
    }

    //Tra ve vị trí người có quân bài được thu về
    public int NguoiChoiGomBai(ArrayList<Card> lstQuanBai) {
        int flag = 0;
        if (lstQuanBai.size() > 0) {
            for (int i = 0; i < lstQuanBai.size(); i++) {
                //Kiem tra do thang cua quan bai
            }
        }
        return flag;
    }
    static String iPort;
    static String sIP;

    public static void main(String args[]) {
        Al client = null;
        if (iPort != null && sIP != null) {
            client = new Al(sIP, Integer.parseInt(iPort));
        }

    }
}
